package org.codeart.apipassenger.service;

import cn.hutool.core.util.StrUtil;
import org.codeart.common.constant.TokenEnum;
import org.codeart.common.util.HttpStatus;
import org.codeart.common.util.R;
import org.codeart.common.dto.TokenResult;
import org.codeart.common.response.TokenResponse;
import org.codeart.common.util.JwtUtils;
import org.codeart.common.util.RedisPrefixUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class TokenService {
    
    @Autowired
    private StringRedisTemplate redisTemplate;
    
    public R<TokenResponse> refreshToken(String refreshToken) {
        // 解析refreshToken
        TokenResult tokenResult = JwtUtils.checkToken(refreshToken);
        if (tokenResult == null) {
            return R.fail(HttpStatus.TOKEN_ERROR, "Token错误");
        }
        
        String phone = tokenResult.getPhone();
        String identity = tokenResult.getIdentity();
                
        // 读取redis中的refreshToken
        String refreshTokenKey = RedisPrefixUtil.generateTokenKey(phone, identity, TokenEnum.REFRESH_TOKEN.value());
        String redisFreshToken = redisTemplate.opsForValue().get(refreshTokenKey);

        // 校验token
        if (StrUtil.isEmpty(redisFreshToken) || !refreshToken.trim().equals(redisFreshToken.trim())) {
            return R.fail(HttpStatus.TOKEN_ERROR, "Token错误");
        }
        
        // 生成双token
        String newRefreshToken = JwtUtils.generateToken(phone, identity, TokenEnum.REFRESH_TOKEN.value());
        String accessToken = JwtUtils.generateToken(phone, identity, TokenEnum.ACCESS_TOKEN.value());
        
        String accessTokenKey = RedisPrefixUtil.generateTokenKey(phone, identity, TokenEnum.ACCESS_TOKEN.value());
        redisTemplate.opsForValue().set(accessTokenKey, accessToken, 30, TimeUnit.DAYS);
        redisTemplate.opsForValue().set(refreshTokenKey, newRefreshToken, 31, TimeUnit.DAYS);

        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setRefreshToken(newRefreshToken).setAccessToken(accessToken);
        
        return R.ok(tokenResponse);
    }

}
